﻿using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using Portal.Data.Entity;

namespace Portal.Data.Crawler
{
    public class Vitaku
    {
        #region ctor
        private static readonly HtmlParser _parser = new HtmlParser();
        private static class Singleton
        {
            public static readonly Vitaku Instance = new Vitaku();
        }
        public static Vitaku Instance
        {
            get
            {
                return Singleton.Instance;
            }
        }
        #endregion

        #region Config

        private const string DomainLink = "http://vitaku.com";
        const string OpenChapItem = "<div style=\"width";
        const string CloseChapItem = "</div>";

        #endregion

        /// <summary>
        /// Get list new chap update. Return number of chap updated
        /// </summary>
        public int GetNewChaps(Book b, out string errorMessage)
        {
            int newcount = 0;
            var sources = Common.GetHtmlSources(b.CrawlUrl);
            if (sources.Length > 0)
            {
                sources = _parser.Replace(sources, HtmlParser.Patterns.BREAK, " ");
                try
                {
                    var ccl = new CommonCrawler();

                    //get list chapter
                    var allExisted = Content.FindByBook(b.ID).Select(x => x.CrawlUrl).ToList();

                    var blocklistchap = _parser.GetContentInNode(sources, OpenChapItem, CloseChapItem);
                    if (blocklistchap.Count > 0)
                    {
                        var allChapFromSource = _parser.GetBetweenTag(blocklistchap[0], "a");
                        //loc qua 1 lan, bo qua cac link ko co noi dung
                        var realItems = (from Match item in allChapFromSource let clear = _parser.RemoveAllTag(item.Value).Trim() where clear.Length > 0 select item.Value).ToList();
                        int totalFromSource = realItems.Count;
                        if (totalFromSource > allExisted.Count)
                        {
                            var newLastChapId = 0;
                            var idx = 1;
                            //(index =0 la chuong moi nhat)
                            while (idx <= totalFromSource)
                            {
                                var item = realItems[totalFromSource - idx];
                                var chap = new Content { Book_ID = b.ID, Chapter = allExisted.Count + 1, SafeNameBook = b.SafeName };

                                var urls = _parser.GetProperty(item, "href");
                                if (urls.Count > 0)
                                {
                                    var crawlUrl = urls[0].Groups[4].Value.Trim();
                                    chap.CrawlUrl = Common.FillAbsoluteLink(DomainLink, crawlUrl);
                                }
                                if (!allExisted.Contains(chap.CrawlUrl))
                                {
                                    allExisted.Add(chap.CrawlUrl);//add into existed

                                    chap.Title = HttpUtility.HtmlDecode(_parser.RemoveAllTag(item).Trim());
                                    chap.BodyTemp = ccl.GetChapBody(chap.CrawlUrl, out errorMessage);
                                    chap.Broken = chap.BodyTemp.Length == 0;
                                    chap.Save();
                                    newLastChapId = chap.Content_ID;

                                    newcount++;
                                }

                                //vẫn tiếp tục tăng số chương, để bỏ qua các chap "ngoại truyện"
                                idx++;
                            }
                            if (newLastChapId > 0)
                                b.ChangeLastChap(newLastChapId, allExisted.Count);
                        }
                    }
                }
                catch (Exception ex)
                {
                    errorMessage = ex.Message;
                    return newcount;
                }
            }
            errorMessage = "";
            return newcount;
        }
    }
}

